package com.archermind.style.service;

import com.archermind.style.bean.Icon;
import com.archermind.style.bean.IconDistri;
import com.archermind.style.bean.IconType;
import com.archermind.style.bean.User;
import com.archermind.style.pojo.Constants;
import com.archermind.style.pojo.IconTypeEnum;
import com.feng.fengDUtil.BaseService;
import com.archermind.style.util.ImageUtil;
import com.archermind.style.util.Search;
import com.archermind.style.util.SessionUtil;
import com.feng.fengDUtil.Page;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Transactional
public class IconService extends BaseService {

    private static final Logger log = LoggerFactory.getLogger(IconService.class);

    /** 图片上传大小限制10M */
    public static final long IMG_MAXSIZE = 10240000;
    /**临时图片存放路径*/
    public static final String TEMP_UPLOAD_PATH ="/images/upload/";



    public Page query(Page page,Search search) {
        ArrayList params = new ArrayList();
        String sql = "select u.*,d.iconType,d.scaleId from icon u left join icon_distri d on u.name = d.name where 1=1 ";
        if(StringUtils.isNotEmpty(search.getName())){
            sql+=" and u.name like ?";
            params.add(processLike(search.getName()));
        }
        if(search.getFolderId()!=null){
            sql+=" and u.typeId = ?";
            params.add(search.getFolderId());
        }
        if(search.getTypeId()!=null){
            if(search.getTypeId()==1){
                sql+=" and (d.iconType = 1 or d.iconType is null)";
            }else{
                sql+=" and d.iconType = 2";
            }
        }
        if(new Integer(1).equals(search.getRepeatName())){
            sql+=" and exists (select 1 from icon x where x.typeId = u.typeId and  x.name = u.name and x.id!=u.id )";
        }

        sql+="  order by cast(u.name as DECIMAL) asc";
        findPageList(Icon.class,sql,page,params.toArray());
        return page;
    }


    public Page listSprite(Page page,Search search) {
        Integer folderId = sql("select folderId from instance where id = ?").one(Integer.class,search.getInstanceId());
        ArrayList params = new ArrayList();
        String sql = "select u.*,d.iconType," +
                "(select i.path From icon i where i.typeId = "+folderId+" and i.name = u.fileName limit 1 ) path" +
                " from instance_icon u left join icon_distri d on u.fileName = d.name where instanceId = ?";
        params.add(search.getInstanceId());
        if(search.getTypeId()!=null){
            if(search.getTypeId()==1){
                sql+=" and (d.iconType = 1 or d.iconType is null)";
            }else{
                sql+=" and d.iconType = 2";
            }
        }
        if(StringUtils.isNotEmpty(search.getName())){
            sql+=" and fileName like ?";
            params.add(processLike(search.getName()));
        }
        sql+="   order by cast(u.fileName as DECIMAL) asc";
        findPageList(Map.class,sql,page,params.toArray());
        return page;
    }

    public String getIconPath(String typeName,String iconName){
        String path= sql("select i.path from icon i join icon_type t on i.typeId = t.id where t.text = ? and  i.name = ? limit 1").one(String.class,typeName,iconName);
        return path;
    }

    public String getIconPath(Integer folderId,String iconName){
        String path= sql("select i.path from icon i where i.typeId = ? and i.name = ? limit 1").one(String.class,folderId,iconName);
        if(path == null){
            path= sql("select i.path from icon i where i.typeId = ? and replace(replace(i.name,'@3x.','.'),'@2x.','.') = ? limit 1").one(String.class,folderId,iconName);
        }
        return path;
    }

    /**
     * 单个查询效率低，暂时废弃使用
     * @param folderId
     * @param iconName
     * @return
     */
    @Deprecated
    public Icon getIcon(Integer folderId,String iconName){
        Icon icon= sql("select * from icon i where i.typeId = ? and replace(replace(i.name,'@3x.','.'),'@2x.','.') = ? limit 1").one(Icon.class,folderId,iconName);
        return icon;
    }

    /**
     * 获取同一目录下在所有图标，用于导出xml
     * @param folderId
     * @return
     */
    public HashMap<String,Icon> getAllIcons(Integer folderId) {
        HashMap<String,Icon> map = new HashMap<>();
        List<Icon> list = sql("select * from icon i where i.typeId = ?").list(Icon.class,folderId);
        for(Icon icon:list){
            map.put(icon.getName().replaceAll("@\\dx.","."),icon);
        }
        return map;
    }


    public IconTypeEnum getIconType(String name){
        Integer iconType = sql("select iconType from icon_distri where name = ?").one(Integer.class,name);
        if(iconType==null || iconType == 1){
            return IconTypeEnum.image;
        }
        return IconTypeEnum.sprite_sheet;
    }

    public void editIcons(Integer[] ids, String[] names,Integer[] scaleIds) {
        List<Object[]> params = new ArrayList<>();
        List<IconDistri> list = new ArrayList<>();
        for(int i=0;i<ids.length;i++){
            params.add(new Object[]{names[i],ids[i]});
            list.add(new IconDistri(names[i],1,scaleIds[i]));
        }
        String sql = "update icon set name = ? where id = ?";
        batch(sql,params);
        saveOrUpdateAll(list);
    }

    public String saveImage(MultipartFile file, Icon icon) throws Exception{
        if(file.getSize()> IMG_MAXSIZE){
            throw new Exception("Uploading image size exceeds 10M！");
        }
        String relativeFolder = TEMP_UPLOAD_PATH+"/";

        String nowTime = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
        String fileName = nowTime+"_"+ UUID.randomUUID()+ ImageUtil.getFileExt(file);
        //如果上传目录为/static/images/upload/，则可以如下获取：
        File absFolder = new File(Constants.webRoot.getAbsolutePath(),relativeFolder);
        if(!absFolder.exists()) absFolder.mkdirs();
        System.out.println("upload url:"+absFolder.getAbsolutePath());
        //在开发测试模式时，得到的地址为：{项目跟目录}/target/static/images/upload/
        //在打包成jar正式发布时，得到的地址为：{发布jar包目录}/static/images/upload/
        File oriFile = new File(absFolder,fileName);
        file.transferTo(oriFile);
        Integer[] dimension = ImageUtil.getDimension(oriFile);

        String miniFileName = ImageUtil.getMiniPath(oriFile.getAbsolutePath(),"_min");

        ImageUtil.saveAsImage(oriFile,miniFileName,48,48,true);
        icon.setWidth(dimension[0]);
        icon.setHeight(dimension[1]);
        icon.setPath(relativeFolder+fileName);
        return relativeFolder+fileName;
    }

    public Object isUnique(String iconName, Integer folderId, String ids) {
        ArrayList params = new ArrayList();
        String[] idArray = ids.split(",");
        String sql = "select 1 from icon where name = ? and typeId = ? and id not in ("+genePlaceHolders(idArray.length)+") limit 1";
        params.add(iconName);
        params.add(folderId);
        params.addAll(Arrays.asList(idArray));
        Long one = sql(sql).one(Long.class, params.toArray());
        return one == null;
    }


    public List<Icon> getIconByIds(String ids){
        String[] idArray = ids.split(",");
        List<Icon> icons = sql("select * from icon where id in ("+genePlaceHolders(idArray.length)+")").list(Icon.class,idArray);
        return icons;
    }

    public List<Icon> selectExistsIcons(Integer typeId, List<String> names) {
        ArrayList params = new ArrayList();
        params.add(typeId);
        params.addAll(names);
        List<Icon> icons = sql("select * from icon where typeId = ? and name in ("+genePlaceHolders(names.size())+")").list(Icon.class,params.toArray());
        return icons;
    }

    public File getIconFile(Icon icon){
       return new File(Constants.webRoot.getAbsolutePath(),icon.getPath());
    }

    public void delIcons(String ids) throws Exception{
        List<Icon> icons = getIconByIds(ids);
        for(Icon icon:icons){
            File file = getIconFile(icon);
            if(file.exists()){
                file.delete();
            }
            String miniFileName = ImageUtil.getMiniPath(file.getAbsolutePath(),"_min");
            File miniFile = new File(miniFileName);
            if(miniFile.exists()){
                miniFile.delete();
            }
        }
        deleteByIds(Icon.class,ids);
    }


    public Integer getIconType(String instanceId, String iconName) {
        Integer iconType= sql("select i.iconType from instance_icon i  where i.instanceId = ? and i.fileName = ? limit 1").one(Integer.class,instanceId,iconName);
        return iconType;
    }

    public void shiftType(String[] names, Integer iconType) {
        List<IconDistri> list = new ArrayList<>();
        for(String name:names){
            list.add(new IconDistri(name,iconType));
        }
        saveOrUpdateAll(list);
    }

    public void repairDimension() throws IOException {
        List<Icon> icons = null;
        while (icons == null ||icons.size()>0){
            icons = sql("select * from icon where width is null and path is not null limit 10").list(Icon.class);
            for(Icon icon:icons){
                File file = getIconFile(icon);
                Integer[] dimension = ImageUtil.getDimension(file);
                icon.setWidth(dimension[0]);
                icon.setHeight(dimension[1]);
            }
            saveOrUpdateAll(icons);
        }
    }

    public List<IconType> listIconFolder() {
        ArrayList params = new ArrayList();
        String sql = "select * from icon_type u where 1=1 ";
        User user = SessionUtil.getCurUser();
        if(!new Integer(1).equals(user.getId())){
            Set instanceIds =  SessionUtil.getInstanceIds(user);
            if(instanceIds.isEmpty()){
                return Collections.emptyList();
            }
            sql+=" and u.id in  (select i.folderId from instance i where i.id in ("+genePlaceHolders(instanceIds.size())+") )";
            params.addAll(instanceIds);
        }
        return sql(sql).list(IconType.class,params.toArray());
    }

    @Transactional
    public void test(){
        sql("insert into attachment_folder(id,code) values ('100','100')").update(null);
    }
}
